using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using DslCrossModelFramework.ModelTraversal;
using Microsoft.VisualStudio.Modeling;

namespace DslCrossModelFramework.ModelRelationship {
    public class DefaultModelRelationshipDefinition : IModelRelationshipDefinition {
        public DefaultModelRelationshipDefinition()
            : this(null) {
        }

        public DefaultModelRelationshipDefinition(Type modelRootType) {
            this.modelRootType = modelRootType;
            this.parentType = typeof (ModelElement);
        }

        public ReadOnlyCollection<ModelElement> GetChildModelElements(ModelPath parentPath, CrossModelManager manager, String scope) {
            if(parentPath.TargetModelElement.GetType() == modelRootType) {
                // return all the expected types under the model root
                return new ReadOnlyCollection<ModelElement>( 
                                new ModelElementExcludeTypeFilter(
                                    new Type[]{modelRootType}).FilterCollection(
                                        manager.GetModelDirectory().FindAllElementsInModel(parentPath.TargetModelElement)));
            }
            else {
                return new ReadOnlyCollection<ModelElement>(new List<ModelElement>());
            }
        }

        public List<ModelPath> GetChildPaths(ModelPath parentPath, CrossModelManager manager, String scope) {
            ReadOnlyCollection<ModelElement> children = this.GetChildModelElements(parentPath, manager, scope);
            List<ModelPath> modelPaths = new List<ModelPath>();
            foreach(ModelElement child in children) {
                ModelPath newPath = parentPath.Clone() as ModelPath;
                newPath.Merge(new ModelPath(parentPath.TargetModelElement, child, scope));
                modelPaths.Add(newPath);
            }
            return modelPaths;
        }

        public Type ParentType {
            get { return parentType; }
            set { parentType = value; }
        }
        private Type parentType;


        public Type ModelRootType {
            get { return modelRootType; }
            set{ modelRootType = value;}
        }
        private Type modelRootType;

    }
}